package com.lry.jvm.jnative.java.lang;

import com.lry.jvm.jnative.NativeMethod;
import com.lry.jvm.jnative.Registry;
import com.lry.jvm.rtda.Frame;
import com.lry.jvm.rtda.JObject;
import com.lry.jvm.rtda.heap.JClass;
import com.lry.jvm.util.Util;

public class _Object {

    public static void init(Frame frame){
        Registry.register("java/lang/Object","getClass","()Ljava/lang/Class;",getClass(frame));
        Registry.register("java/lang/Object", "hashCode", "()I", hashCode(frame));
        Registry.register("java/lang/Object", "clone", "()Ljava/lang/Object;", clone(frame));
    }

    public static NativeMethod getClass(Frame frame){
        JObject jObject = frame.getLocalVars().getRef(0);
        JObject ref = jObject.getJClass().getJClass();
        frame.getOperandStack().pushRef(ref);
        return new NativeMethod(frame);
    }

    public static NativeMethod hashCode(Frame frame){
        JObject jObject = frame.getLocalVars().getRef(0);
        int hash = jObject.hashCode();
        frame.getOperandStack().pushInt(hash);
        return new NativeMethod(frame);
    }

    public static NativeMethod clone(Frame frame){
        JObject jObject = frame.getLocalVars().getRef(0);
        JClass cloneable = jObject.getJClass().getLoader().loadClass("java/lang/Cloneable");
        if (!jObject.getJClass().isImplements(cloneable)) {
            Util.panic("java.lang.CloneNotSupportedException");
        }
        frame.getOperandStack().pushRef(jObject.cloneObj());
        return new NativeMethod(frame);
    }

}
